<script setup>
import {ref, watch} from "vue";
import {useUserStore} from '@/store/user.js'
import axios from 'axios'
import router from "@/router/index.js";

// 视图状态
const loginStatus = ref('login')
//二维码内容
const qrcodeUrl = ref('');
const qrcodeKey = ref('');
const status = ref('waiting'); // waiting | scanned | timeout
const token = ref(''); //token
const pollInterval = ref(null); // 轮询定时器
const cookieActive = ref(true);//BiliBili cookie active or not
//用户信息存储
const userStore = useUserStore();
// 登录表单数据
const loginForm = ref({
  username: "",
  password: "",
  qrcode_key:"",
});

// 注册表单数据
const registerForm = ref({
  username: "",
  password: "",
  confirmPassword: "",
});

// 错误消息
const loginError = ref("");
const registerError = ref("");
const usernameError = ref("");
const passwordMatchError = ref("");

// 密码强度相关
const passwordStrength = ref(0);
const passwordStrengthText = ref("");
const passwordStrengthClass = ref("");
const passwordStrengthTextClass = ref("");

//二维码处理版本
const loginBilibili = async () => {
  await qrcodeRequest();
  startPolling();
};

//开始轮询
const startPolling = () => {
  pollInterval.value = setInterval(async () => {
        const res = await fetch(`/api/qrcode/poll?qrcode_key=${qrcodeKey.value}`);
        const resp = await res.json();
        const data = resp.data;
        console.log(data)
        if (data.code === 0) {
          status.value = 'scanned';
          cookieActive.value = true;
          console.log(data)
          stopPolling();
        } else if (data.code === 86038) {
          status.value = 'timeout';
          await qrcodeRequest();
        }
      },
      5000
  ); // 每 2 秒轮询一次
};

// 停止轮询
const stopPolling = () => {
  if (pollInterval.value) {
    clearInterval(pollInterval.value);
    pollInterval.value = null;
  }
};

// 切换视图
const switchToRegister = async () => {
  loginStatus.value = 'register';
  await loginBilibili();
  resetErrors();
};

const switchToLogin = () => {
  loginStatus.value = 'login';
  stopPolling();
  resetErrors();
};

const switchForget = async () =>{
  loginStatus.value = 'forget';
  await qrcodeRequest();
  startPolling();
  loginForm.value.qrcode_key = qrcodeKey.value;
  resetErrors();
}

// 重置错误信息
const resetErrors = () => {
  loginError.value = "";
  registerError.value = "";
  usernameError.value = "";
  passwordMatchError.value = "";
};

// 用户名验证
const validateUsername = () => {
  const username = registerForm.value.username;

  // 检查非法字符
  if (!/^[a-zA-Z0-9_]+$/.test(username)) {
    usernameError.value = "用户名只能包含字母、数字和下划线";
    return false;
  }

  // 检查长度
  if (username.length < 3 || username.length > 20) {
    usernameError.value = "用户名长度需在3-20个字符之间";
    return false;
  }

  usernameError.value = "";
  return true;
};

// 密码强度检测
const checkPasswordStrength = () => {
  const password = registerForm.value.password;

  // 重置状态
  passwordStrength.value = 0;
  passwordStrengthText.value = "";

  if (!password) return;

  let strength = 0;

  // 长度检测
  if (password.length >= 8) strength += 25;
  if (password.length >= 12) strength += 15;

  // 包含数字
  if (/\d/.test(password)) strength += 20;

  // 包含小写字母
  if (/[a-z]/.test(password)) strength += 15;

  // 包含大写字母
  if (/[A-Z]/.test(password)) strength += 15;

  // 包含特殊字符
  if (/[^A-Za-z0-9]/.test(password)) strength += 10;

  // 设置强度值和文本
  passwordStrength.value = strength;

  if (strength < 30) {
    passwordStrengthText.value = "密码强度：弱";
    passwordStrengthClass.value = "bg-rate-poor";
    passwordStrengthTextClass.value = "text-rate-poor";
  } else if (strength < 70) {
    passwordStrengthText.value = "密码强度：中等";
    passwordStrengthClass.value = "bg-rate-fair";
    passwordStrengthTextClass.value = "text-rate-fair";
  } else if (strength < 90) {
    passwordStrengthText.value = "密码强度：强";
    passwordStrengthClass.value = "bg-rate-good";
    passwordStrengthTextClass.value = "text-rate-good";
  } else {
    passwordStrengthText.value = "密码强度：非常强";
    passwordStrengthClass.value = "bg-rate-excellent";
    passwordStrengthTextClass.value = "text-rate-excellent";
  }
};
import {doLogin} from "@/api/login.js";
import {doRegister,doForget} from "@/api/register.js";
// 处理登录
const handleLogin = async () => {
  if (!loginForm.value.username || !loginForm.value.password) {
    loginError.value = "请输入用户名和密码";
    return;
  }
  const res = await doLogin(loginForm.value);

  if (res.data.code === 200) {
    loginError.value = "";
    userStore.login(res.data.uid,res.data.cookies);
    await router.push({
        path: "/",
      });
  } else if(res.data.code === 444){
    cookieActive.value = false;
    await qrcodeRequest();
    startPolling();
    loginForm.value.qrcode_key = qrcodeKey.value;
  }
  else {
    loginError.value = "用户名或密码不正确";
    loginForm.value.password = '';
  }
};
//处理忘记密码
const handelForget = async () =>{
  if (!loginForm.value.username || !loginForm.value.password) {
    loginError.value = "请输入用户名和密码";
    return;
  }
    const data = {
    username: registerForm.value.username,
    password: registerForm.value.password,
    qrcode_key: qrcodeKey.value
  }
  const res = await doForget(data);

  if (res.data.code === 200) {
    loginError.value = "";
    console.log(res.data);
    userStore.login(res.data.uid,res.data.cookies);
    await router.push('/');
  }
  else {
    loginError.value = "用户名不存在";
    loginForm.value.password = '';
  }
}
//发送二维码请求
const qrcodeRequest = async () => {
  const res = await fetch(`/api/qrcode`);
  const resp = await res.json();
  console.log(resp)
  const data = resp.data;
  console.log(data)
  qrcodeUrl.value = data.url;
  qrcodeKey.value = data.qrcode_key;
};


//发送注册请求
const registerRequest = async () => {
  const data = {
    username: registerForm.value.username,
    password: registerForm.value.password,
    qrcode_key: qrcodeKey.value
  }

  const res = await doRegister(data);
  const resp = await res.json();
  userStore.login(resp);
};


// 处理注册
const handleRegister = async () => {
  // 重置错误
  registerError.value = "";
  passwordMatchError.value = "";

  // 验证用户名
  if (!validateUsername()) {
    return;
  }

  if (status.value !== 'scanned') {
    registerError.value = "未绑定BiliBili账号";
    return;
  }

  // 验证密码
  if (registerForm.value.password.length < 8) {
    registerError.value = "密码长度至少需要8个字符";
    return;
  }

  // 验证确认密码
  if (registerForm.value.password !== registerForm.value.confirmPassword) {
    passwordMatchError.value = "两次输入的密码不一致";
    return;
  }

  const res = await registerRequest();

  // 注册成功
  registerError.value = "";
  setTimeout(() => {
    window.location.href = '/';
  }, 2000);
};

// 监听确认密码变化
watch(
    () => registerForm.value.confirmPassword,
    (newVal) => {
      if (newVal && registerForm.value.password !== newVal) {
        passwordMatchError.value = "两次输入的密码不一致";
      } else {
        passwordMatchError.value = "";
      }
    }
);
</script>

<template>
  <div class="col-lg-7">
    <div class="form-section">
      <div class="form-container">
        <div class="form-header">
          <h1 class="form-title" style="color: #FB7299" v-if="loginStatus === 'login'">
            用户登录
          </h1>
          <h1 class="form-title" style="color: #FB7299" v-if="loginStatus === 'register'">
            用户注册
          </h1>
          <h1 class="form-title" style="color: #FB7299" v-if="loginStatus === 'forget'">
            重置密码
          </h1>
          <p class="form-subtitle" v-if="loginStatus === 'login'">
            请输入您的账号信息
          </p>
          <p class="form-subtitle" v-if="loginStatus === 'register'">
            请填写注册信息
          </p>
        </div>

        <div v-if="loginStatus === 'login'">
          <!-- 登录表单 -->
          <form @submit.prevent="handleLogin">

            <!-- 账号输入 -->
            <div class="input-group">
              <i class="fa fa-user input-icon"></i>
              <input
                  type="text"
                  class="form-control"
                  v-model="loginForm.username"
                  placeholder=" "
                  required
                  autocomplete="username"
                  aria-label="账号"
              />
              <label class="floating-label">账号</label>
            </div>

            <!-- 密码输入 -->
            <div class="input-group">
              <i class="fa fa-lock input-icon"></i>
              <input
                  type="password"
                  class="form-control"
                  v-model="loginForm.password"
                  placeholder=" "
                  required
                  autocomplete="current-password"
                  aria-label="密码"
              />
              <label class="floating-label">密码</label>
            </div>

            <!-- 错误提示 -->
            <div v-if="loginError" class="error-message" role="alert">
              <i class="fa fa-exclamation-circle me-2"></i>{{ loginError }}
            </div>

            <!-- 记住我 & 忘记密码 -->
            <div class="remember-forgot">
              <div class="form-check">
              </div>
              <a href="#" class="forgot-password" @click="switchForget">忘记密码?</a>
            </div>

            <!-- 登录按钮 -->
            <button
                type="submit"
                class="btn btn-primary w-100 fw-bold"
                aria-label="登录"
                :disabled="!cookieActive"
            >
              <i class="fa fa-sign-in btn-icon"></i>登 录
            </button>


            <!-- 切换到注册 -->
            <div class="switch-container">
              还没有账号?
              <span class="switch-view" @click="switchToRegister"
              >立即注册</span
              >
            </div>
            <div class="qr-section" aria-label="二维码下载区" v-if="!cookieActive">
              <h5 class="qr-title" v-if="status !== 'scanned'">使用BiliBili移动端扫码绑定账号</h5>
              <h5 class="qr-title" v-if="status === 'scanned'">已经成功绑定账号</h5>
              <!-- 二维码生成区域 -->
              <div>
                <vue-qrcode :value="qrcodeUrl" :width="130"></vue-qrcode>
              </div>
            </div>
          </form>
        </div>

        <div v-if="loginStatus === 'register'">
          <!-- 注册表单 -->
          <form @submit.prevent="handleRegister">
            <!-- 用户名 -->
            <div class="input-group">
              <i class="fa fa-user input-icon"></i>
              <input
                  type="text"
                  class="form-control"
                  v-model="registerForm.username"
                  placeholder=" "
                  required
                  @input="validateUsername"
                  autocomplete="off"
                  aria-label="用户名"
              />
              <label class="floating-label">用户名</label>
            </div>
            <div v-if="usernameError" class="error-message" role="alert">
              <i class="fa fa-exclamation-circle me-2"></i>{{ usernameError }}
            </div>

            <!-- 密码 -->
            <div class="input-group">
              <i class="fa fa-lock input-icon"></i>
              <input
                  type="password"
                  class="form-control"
                  v-model="registerForm.password"
                  placeholder=" "
                  required
                  @input="checkPasswordStrength"
                  autocomplete="new-password"
                  aria-label="密码"
              />
              <label class="floating-label">密码：长度至少8个字符</label>
            </div>

            <!-- 密码强度指示器 -->
            <div class="password-strength" aria-hidden="true">
              <div
                  class="password-strength-bar"
                  :class="passwordStrengthClass"
                  :style="{ width: passwordStrength + '%' }"
              ></div>
            </div>
            <div
                class="strength-text"
                :class="passwordStrengthTextClass"
                aria-live="polite"
                aria-atomic="true"
            >
              {{ passwordStrengthText }}
            </div>


            <!-- 确认密码 -->
            <div class="input-group">
              <i class="fa fa-lock input-icon"></i>
              <input
                  type="password"
                  class="form-control"
                  v-model="registerForm.confirmPassword"
                  placeholder=" "
                  required
                  autocomplete="new-password"
                  aria-label="确认密码"
              />
              <label class="floating-label">确认密码</label>
            </div>
            <div v-if="passwordMatchError" class="error-message" role="alert">
              <i class="fa fa-exclamation-circle me-2"></i>{{ passwordMatchError }}
            </div>

            <!-- 错误提示 -->
            <div v-if="registerError" class="error-message" role="alert">
              <i class="fa fa-exclamation-circle me-2"></i>{{ registerError }}
            </div>

            <!-- 注册按钮 -->
            <button
                type="submit"
                class="btn btn-primary w-100 fw-bold"
                aria-label="注册"
                :disabled="status!=='scanned'"
            >
              <i class="fa fa-user-plus btn-icon"></i>注 册
            </button>

            <!-- 切换到登录 -->
            <div class="switch-container">
              已有账号?
              <span class="switch-view" @click="switchToLogin">立即登录</span>
            </div>

            <!-- 二维码区域 - 只在注册界面显示 -->
            <div class="qr-section" aria-label="二维码下载区">
              <h5 class="qr-title" v-if="status !== 'scanned'">使用BiliBili移动端扫码绑定账号</h5>
              <h5 class="qr-title" v-if="status === 'scanned'">已经成功绑定账号</h5>
              <!-- 二维码生成区域 -->
              <div>
                <vue-qrcode :value="qrcodeUrl" :width="130"></vue-qrcode>
              </div>
            </div>
          </form>
        </div>

        <div v-if="loginStatus === 'forget'">
          <!-- 注册表单 -->
          <form @submit.prevent="handelForget">
            <!-- 用户名 -->
            <div class="input-group">
              <i class="fa fa-user input-icon"></i>
              <input
                  type="text"
                  class="form-control"
                  v-model="registerForm.username"
                  placeholder=" "
                  required
                  @input="validateUsername"
                  autocomplete="off"
                  aria-label="用户名"
              />
              <label class="floating-label">用户名</label>
            </div>
            <div v-if="usernameError" class="error-message" role="alert">
              <i class="fa fa-exclamation-circle me-2"></i>{{ usernameError }}
            </div>

            <!-- 密码 -->
            <div class="input-group">
              <i class="fa fa-lock input-icon"></i>
              <input
                  type="password"
                  class="form-control"
                  v-model="registerForm.password"
                  placeholder=" "
                  required
                  @input="checkPasswordStrength"
                  autocomplete="new-password"
                  aria-label="密码"
              />
              <label class="floating-label">密码：长度至少8个字符</label>
            </div>

            <!-- 密码强度指示器 -->
            <div class="password-strength" aria-hidden="true">
              <div
                  class="password-strength-bar"
                  :class="passwordStrengthClass"
                  :style="{ width: passwordStrength + '%' }"
              ></div>
            </div>
            <div
                class="strength-text"
                :class="passwordStrengthTextClass"
                aria-live="polite"
                aria-atomic="true"
            >
              {{ passwordStrengthText }}
            </div>


            <!-- 确认密码 -->
            <div class="input-group">
              <i class="fa fa-lock input-icon"></i>
              <input
                  type="password"
                  class="form-control"
                  v-model="registerForm.confirmPassword"
                  placeholder=" "
                  required
                  autocomplete="new-password"
                  aria-label="确认密码"
              />
              <label class="floating-label">确认密码</label>
            </div>
            <div v-if="passwordMatchError" class="error-message" role="alert">
              <i class="fa fa-exclamation-circle me-2"></i>{{ passwordMatchError }}
            </div>

            <!-- 错误提示 -->
            <div v-if="registerError" class="error-message" role="alert">
              <i class="fa fa-exclamation-circle me-2"></i>{{ registerError }}
            </div>

            <!-- 注册按钮 -->
            <button
                type="submit"
                class="btn btn-primary w-100 fw-bold"
                aria-label="注册"
                :disabled="status!=='scanned'"
            >
              <i class="fa fa-user-plus btn-icon"></i>重置密码
            </button>

            <!-- 切换到登录 -->
            <div class="switch-container">
              已有账号?
              <span class="switch-view" @click="switchToLogin">立即登录</span>
            </div>

            <!-- 二维码区域 - 只在注册界面显示 -->
            <div class="qr-section" aria-label="二维码下载区">
              <h5 class="qr-title" v-if="status !== 'scanned'">使用BiliBili移动端扫码绑定账号</h5>
              <h5 class="qr-title" v-if="status === 'scanned'">已经成功绑定账号</h5>
              <!-- 二维码生成区域 -->
              <div>
                <vue-qrcode :value="qrcodeUrl" :width="130"></vue-qrcode>
              </div>
            </div>
          </form>
        </div>
      </div>

      <!-- 页脚 -->
      <footer class="footer">
        <p>© 2025 用户登录系统 | 保留所有权利</p>
      </footer>
    </div>
  </div>
</template>

<style scoped>
.btn-primary {
  background: linear-gradient(135deg, var(--primary), var(--secondary));
  border: none;
  padding: 0 20px;
  height: var(--btn-height);
  font-weight: 600;
  transition: var(--transition);
  background-size: 200% auto;
  border-radius: 12px;
  font-size: 1.05rem;
  display: flex;
  align-items: center;
  justify-content: center;
  letter-spacing: 0.5px;
}

.btn-primary:hover {
  background-position: right center;
  transform: translateY(-2px);
  box-shadow: 0 10px 20px -5px rgba(251, 114, 153, 0.3);
}

.btn-icon {
  margin-right: 10px;
  font-size: 18px;
}

.form-section {
  padding: 40px;
  display: flex;
  flex-direction: column;
  height: 100%;
}

.form-container {
  position: relative;
  z-index: 10;
}

.form-header {
  text-align: center;
  margin-bottom: 35px;
}

.form-title {
  font-size: 2.2rem;
  font-weight: 700;
  background: linear-gradient(135deg, var(--primary), var(--secondary));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  margin-bottom: 12px;
  transition: var(--transition);
}

.form-subtitle {
  color: #6b7280;
  font-size: 1.05rem;
}

.input-group {
  position: relative;
  margin-bottom: 1.4rem;
}

.input-icon {
  position: absolute;
  top: 50%;
  left: 16px;
  transform: translateY(-50%);
  color: #9CA3AF;
  z-index: 4;
  font-size: 18px;
}

.form-control {
  padding-left: 48px;
  height: var(--input-height);
  border-radius: 12px;
  font-size: 1rem;
  border: 2px solid #e2e8f0;
  transition: var(--transition);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
}

.form-control:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 0.25rem rgba(251, 114, 153, 0.15);
}

.floating-label {
  position: absolute;
  top: 50%;
  left: 50px;
  transform: translateY(-50%);
  transition: var(--transition);
  pointer-events: none;
  color: #9CA3AF;
  background: transparent;
  padding: 0 5px;
  z-index: 3;
}

.form-control:focus ~ .floating-label,
.form-control:not(:placeholder-shown) ~ .floating-label {
  top: -10px;
  left: 45px;
  background: white;
  font-size: 13px;
  color: var(--primary);
  z-index: 5;
  font-weight: 500;
}


.password-strength {
  height: 6px;
  border-radius: 3px;
  margin-top: 8px;
  background: #e2e8f0;
  overflow: hidden;
}

.password-strength-bar {
  height: 100%;
  transition: var(--transition);
}

.strength-text {
  font-size: 13px;
  margin-top: 6px;
  text-align: right;
  font-weight: 500;
}

.password-rules ul {
  padding-left: 20px;
  margin-bottom: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 5px;
}

.password-rules li {
  margin-bottom: 4px;
}

.switch-container {
  text-align: center;
  margin-top: 20px;
  font-size: 15px;
  color: #6b7280;
}

.switch-view {
  color: var(--primary);
  cursor: pointer;
  font-weight: 600;
  margin-left: 6px;
  transition: var(--transition);
  position: relative;
  display: inline-block;
}

.switch-view:hover {
  color: var(--secondary);
}

.switch-view::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 0;
  height: 2px;
  background: var(--secondary);
  transition: var(--transition);
}

.switch-view:hover::after {
  width: 100%;
}

.qr-section {
  background: rgba(255, 255, 255, 0.8);
  border-radius: 16px;
  padding: 20px;
  text-align: center;
  margin-top: 30px;
  border: 1px solid rgba(0, 0, 0, 0.05);
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
  animation: fadeInUp 0.5s ease;
}

.qr-title {
  font-weight: 600;
  margin-bottom: 15px;
  color: #4b5563;
}

.error-message {
  color: #ef4444;
  font-size: 14px;
  margin-top: 8px;
  padding: 8px 12px;
  background: #fef2f2;
  border-radius: 8px;
  border: 1px solid #fee2e2;
  animation: fadeIn 0.3s ease;
}

.remember-forgot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 20px 0;
}

.form-check {
  display: flex;
  align-items: center;
}

.form-check-input {
  width: 20px;
  height: 20px;
  margin-right: 8px;
  border-radius: 5px;
  border: 1px solid #d1d5db;
}

.form-check-label {
  color: #4b5563;
  font-size: 14px;
}

.forgot-password {
  color: var(--primary);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  transition: var(--transition);
}

.forgot-password:hover {
  color: var(--secondary);
  text-decoration: underline;
}

.footer {
  text-align: center;
  margin-top: 40px;
  color: #6b7280;
  font-size: 14px;
  padding-top: 20px;
  border-top: 1px solid #edf2f7;
}

</style>